﻿using Microsoft.AspNetCore.Http.Features;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using UAParser;

namespace Ids4.Api.Application.Extensions
{
    /// <summary>
    /// HttpContext扩展类
    /// </summary>
    public static class HttpContextExtension
    {

        /// <summary>
        /// 是否是ajax请求
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static bool IsAjaxRequest(this HttpRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            return request.Headers["X-Requested-With"] == "XMLHttpRequest" || (request.Headers != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }

        /// <summary>
        /// 获取客户端IP
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetClientUserIp(this HttpContext context)
        {
            if (context == null)
            {
                return "";
            }

            var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (string.IsNullOrEmpty(result))
            {
                result = context.Connection.RemoteIpAddress?.ToString();
            }
            if (string.IsNullOrEmpty(result) || result.Contains("::1"))
            {
                result = "127.0.0.1";
            }

            result = result.Replace("::ffff:", "127.0.0.1");
            result = IsIP(result) ? result : "127.0.0.1";
            return result;
        }

        /// <summary>
        /// GetClientInfo
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static UAParser.ClientInfo GetClientInfo(this HttpContext context)
        {
            var str = GetUserAgent(context);
            var uaParser = Parser.GetDefault();
            UAParser.ClientInfo c = uaParser.Parse(str);

            return c;
        }

        /// <summary>
        /// 判断是否是Ip
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        /// <summary>
        /// 获取请求令牌
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetToken(this HttpContext context)
        {
            return context.Request.Headers["Authorization"];
        }

        /// <summary>
        /// GetUserAgent
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetUserAgent(this HttpContext context)
        {
            return context.Request.Headers["User-Agent"];
        }

        /// <summary>
        /// Token用户Id
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static long GetUId(this HttpContext context)
        {
            var uid = context.User.FindFirstValue(ClaimTypes.PrimarySid);

            return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0;
        }

        /// <summary>
        /// 认证用户名称
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string? GetName(this HttpContext context)
        {
            var uid = context.User?.Identity?.Name;

            return uid;
        }

        /// <summary>
        /// ClaimsIdentity
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static IEnumerable<ClaimsIdentity>? GetClaims(this HttpContext context)
        {
            return context.User?.Identities;
        }

        /// <summary>
        /// 请求Url
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string? GetRequestUrl(this HttpContext context)
        {
            return context != null ? context.Request.Path.Value : "";
        }

        /// <summary>
        /// 请求参数
        /// </summary>
        /// <param name="context"></param>
        public static async Task<string> GetRequestValue(this HttpContext context)
        {
            string param;

            string reqMethod = context.Request.Method;

            if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod))
            {
                using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8))
                {
                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
                    param = await reader.ReadToEndAsync();
                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
                }
            }
            else
            {
                param = context.Request.QueryString.Value?.ToString();
            }

            return param;
        }

        /// <summary>
        /// RequestDataLog
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private static async Task RequestDataLog(HttpContext context)
        {
            var request = context.Request;
            var sr = new StreamReader(request.Body);

            var res = await sr.ReadToEndAsync();

            #region 记录详细请求明文信息
            var content = $"Route:{request.Path + request.QueryString}\r\n BodyData:{res}";
            #endregion

            await Task.CompletedTask;

        }

        /// <summary>
        /// Endpoint
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static Endpoint GetEndpoint(this HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            return context.Features.Get<IEndpointFeature>()?.Endpoint;
        }
    }
}
